package encapsulation

import "fmt"

// ==========封装==========
// 1、封装的意义在于保护或者防止代码(数据)被随意篡改, 保护成员属性, 不让类以外的程序直接访问和修改
// 2、封装原则: 隐藏对象的属性和实现细节, 仅对外公开访问方法, 并控制访问级别. 用类来实现封装, 用封装来实现高内聚、低耦合
//  - 内聚: 一个模块内部各个部分之间的关联程度
//  - 耦合: 各个模块之间的关联程度
// 3、在golang中封装就是把抽象出来的字段和对字段的操作封装在一起, 数据被保护在内部, 程序的其它包只能通过被授权的方法, 才能对字段进行操作.
// 4、封装的好处
//  - 隐藏实现细节
//  - 可以对数据进行验证, 保证数据安全合理
// 5、如何体现封装
//  - 对结构体中的属性进行封装
//  - 通过方法、包来实现封装
// 6、封装的实现步骤
//  - 将结构体、字段的首字母小写
//  - 给结构体所在的包提供一个工厂模式的函数, 首字母大写, 类似一个构造函数
//  - 提供一个首字母大写的Set方法, 用于对属性判断并赋值
//  - 提供一个首字母大写的Get方法, 用于获取属性的值

// 案例: 不能随便查看人的年龄、工资等隐私信息, 并对输入的年龄进行合理的验证
type person struct {
	Name   string
	age    uint8
	salary float64
}

func (p *person) GetAge() uint8 {
	return p.age
}

func (p *person) SetAge(age uint8) {
	if age <= 0 || age >= 150 {
		fmt.Println("年龄范围有误")
		return
	}
	p.age = age
}

func (p *person) GetSalary() float64 {
	return p.salary
}

func (p *person) SetSalary(salary float64) {
	if salary <= 1000 || salary >= 1000000 {
		fmt.Println("薪资范围有误")
		return
	}
	p.salary = salary
}

func Factory(name string) *person {
	return &person{Name: name}
}
